// 2013-9-12上午12:10:45  net.betou.trade.main.manager.role.impl.AgencyRoleMngImpl.java

package net.betou.trade.main.manager.role.impl;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import net.betou.common.hibernate3.Updater;
import net.betou.common.hibernate3.Updater.UpdateMode;
import net.betou.common.page.Pagination;
import net.betou.common.util.DataConvertUtils;
import net.betou.trade.entity.main.AgentAndAdmins;
import net.betou.trade.entity.main.Role;
import net.betou.trade.main.dao.role.AgencyRoleDao;
import net.betou.trade.main.manager.role.AgencyRoleMng;
import net.betou.trade.role.setting.RoleFinderConfig;
import net.betou.trade.web.DBConstants;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 角色的可见度, 完全决定了后面的数据
 * @author 叶装装
 */
@Service
@Transactional
public class AgencyRoleMngImpl implements AgencyRoleMng{
	
	/**
	 * @version 1.1 只显示出自己的
	 */
	@Transactional( readOnly = true )
	public Pagination getPage( AgentAndAdmins admin, String searchProperty, String searchValue, String orderProperty, String orderDirection, int pageSize, int pageNo ) {
		boolean system = admin.getSystem( );
		
		if( system ){
			return dao.getPage( null, null, searchProperty, searchValue, orderProperty, orderDirection, pageSize, pageNo );
		}else{
			// 隐藏机构
			Integer level = admin.getSearchSettingRole( ).getLevel( );
			return dao.getPage( level , admin.getId( ), searchProperty, searchValue, orderProperty, orderDirection, pageSize, pageNo, DBConstants.DEFINED_AGENCY_IDENTITY );
			//return dao.getPage( level , admin.getId( ), searchProperty, searchValue, orderProperty, orderDirection, pageSize, pageNo, null );
		}
	}
	
	@Transactional( readOnly = true )
	public Role findRole( AgentAndAdmins admin, Integer id ){
		
		boolean system = admin.getSystem( );
		
		if( system ){
			return dao.findById( id );
		}
		
		return dao.findBySelf( admin.getId( ), id );
	}
	
	@Transactional( readOnly = true )
	public Role findById( Integer id ){
		return dao.findById( id );
	}
	
	@Transactional( readOnly = true )
	public Role findAgencyByDefault( ){
		return dao.findByIdentity( DBConstants.SYSTEM_AGENCY_IDENTITY );
	}
	
	@Transactional( readOnly = true )
	public Role findProxyByDefault( ){
		return dao.findByIdentity( DBConstants.SYSTEM_PROXY_IDENTITY );
	}
	
	@SuppressWarnings( "unchecked" )
	@Transactional( readOnly = true )
	public List< Role > list( AgentAndAdmins admin, AgentAndAdmins editAdmin ){
		
		boolean system = admin.getSystem( );
		
		AgentAndAdmins configAdmin = system ? editAdmin : admin;
		
		RoleFinderConfig config = new RoleFinderConfig( configAdmin );
		
		Integer level =  configAdmin.getSearchSettingRole( ).getLevel( );
		
		if( config.isSelf( ) ){
			return dao.findList( level, configAdmin.getId( ) );
		}
		
		config.setEnd( " and role_level>=" + level );
		// 设置一个够大的值, 基本上角色是不可能超过100个
		return ( List< Role >) dao.getPageByCriteria( null, null, null, null, 1, 100, config.getDeepSQL( ) ).getList( );
		
	}
	
	@Transactional( readOnly = true )
	public Role findAgencyBySelf( AgentAndAdmins admin ){
		Integer id = admin.getId( );
		if( admin.getDeep( ) > 0 ){
			id = DataConvertUtils.getInt( StringUtils.split( admin.getTopIntermedia( ), ",")[ 0 ] );
		}
		return dao.findDefaultBySelf( id, DBConstants.DEFINED_AGENCY_IDENTITY );
	}
	
	@Transactional( readOnly = true )
	public List< Role > listBySelf( AgentAndAdmins admin ){
		return dao.findListNotDefault( admin.getSearchSettingRole( ).getLevel( ), admin.getId( ) );
	}
	
	@Transactional( readOnly = true )
	public Role findProxyBySelf( AgentAndAdmins admin ){
		Integer id = admin.getId( );
		if( admin.getDeep( ) > 0 ){
			id = DataConvertUtils.getInt( StringUtils.split( admin.getTopIntermedia( ), ",")[ 0 ] );
		}
		return dao.findDefaultBySelf( id, DBConstants.DEFINED_PROXY_IDENTITY );
	}
	
	@Transactional( readOnly = true )
	public Role findProxyBySelf( Integer id ){
		return dao.findDefaultBySelf( id, DBConstants.DEFINED_PROXY_IDENTITY );
	}
	
	@Transactional( readOnly = true )
	public List< Role > findListByAllowInitToAgency( ){
		return dao.findListByAllowInit( null );
	}
	
	@Transactional( readOnly = true )
	public List< Role > findListByAllowInitToProxy( ){
		return dao.findListByAllowInit( false );
	}
	
	public Role save( Role bean ){
		dao.save( bean );
		return bean;
	}
	public Role save( AgentAndAdmins admin, Role bean, Set< String > perms ){
		bean.saveToAgency( admin );
		
		Integer level = dao.maxLevel( admin.getId( ) );
		
		if( level == 0 ){
			level = admin.getDeep( );
		}

		bean.setLevel( level + 1 );
		bean.setPerms( perms );
		
		dao.save( bean );
		
		return bean;
	}
	
	
	public Role update( String description, Integer level, String name, Role bean, Set< String > perms ){
		
		bean.update( description, level, name );
		bean.setPerms( perms );
		
		Updater< Role > updater = new Updater< Role >( bean );
		
		updater.exclude( "roleDefault" ); // 不更新是否默认
		updater.exclude( "allowRead" );
		updater.exclude( "identity" ); // 不包括这三种
		updater.exclude( "admin" );
		bean = dao.updateByUpdater( updater );
		
		return bean;
	}
	
	public Role update( Role bean, Set< String > items ){
		
		if( items != null ){
			bean.setShares( items );
		}
		Updater< Role > updater = new Updater< Role >( bean, UpdateMode.MIN );
		
		if( items != null ){
			
			updater.include( "shares" );
		}
		bean = dao.updateByUpdater( updater );
		
		return bean;
	
		
	}
	
	
	public Role [ ] deleteByIds( Integer [ ] ids ){
		Role [ ] beans = new Role [ ids.length ];
		for ( int i = 0, len = ids.length; i < len; i++ ){
			beans[ i ] = dao.deleteById( ids[ i ] );
		}
		return beans;
	}
	
	public Role [] findListByAdminIds ( Integer [ ] adminIds ){
		HashSet<Role> rs = new HashSet<Role>();
		if(adminIds!=null){
			for(Integer id : adminIds){
				List<Role> list = dao.findList(null, id);
				rs.addAll(list);
			}
		}
		return rs.toArray(new Role[rs.size()]);
	}

	@Autowired
	private AgencyRoleDao dao;
}
